package org.jvm.classpath;

import org.jvm.classpath.entry.*;

import java.io.File;

/**
 * 总类路径持有三个分类路径
 * 1、根类路径
 * 2、扩展类路径
 * 3、用户类路径
 *
 * @author 海燕
 * @date 2023/1/5
 */
public class BootClassPath {

    /**
     * 根类路径
     */
    private final Entry bootClassPath;
    /**
     * 扩展类路径
     */
    private final Entry extClassPath;
    /**
     * 用户类路径
     */
    private final Entry userClassPath;

    private boolean useExt = false;

    public void setUseExt(boolean useExt) {
        this.useExt = useExt;
    }

    /**
     * 读取类的顺序为根类路径->扩展类路径->用户类路径
     *
     * @param className
     * @return
     */
    public byte[] readClass(String className) {
        className = className.concat(".class");
        //   Entry[] entryList = new Entry[]{bootClassPath, extClassPath, userClassPath};
        Entry[] entryList;
        if (useExt) {
            entryList = new Entry[]{bootClassPath, extClassPath};
        } else {
            entryList = new Entry[]{bootClassPath};
        }
        for (int i = 0; i < entryList.length; i++) {
            byte[] res = entryList[i].readClass(className);
            if (res != null) {
                return res;
            }
        }
        return null;
    }

    /**
     * @param jreOption 根类路径，+ext扩展类路径
     * @param cpOption  用户类路径
     */
    public BootClassPath(String jreOption, String cpOption) {
        String jreDir = getJreDir(jreOption);
        this.bootClassPath = EntryBuilder.newEntry(jreDir + File.separator + "lib" + File.separator + "*");
        this.extClassPath = EntryBuilder.newEntry(jreDir + File.separator + "lib" + File.separator + "ext" + File.separator + "*");
        //如果用户类路径缺失，默认使用当前路径
        if (cpOption == null || cpOption.equals("")) {
            cpOption = ".";
        }
        this.userClassPath = EntryBuilder.newEntry(cpOption);

    }

    /**
     * 首先使用用户指定的jre目录
     * 其次如果用户没有指定，则使用当前目录
     * 再次如果当前目录不存在，使用系统变量配置的JAVA_HOME
     *
     * @param jreOption
     * @return
     */
    private String getJreDir(String jreOption) {
        if (jreOption != null && jreOption.length() > 0 && dirExists(jreOption)) {
            return jreOption;
        }
        if (dirExists("./jre")) {
            return "./jre";
        }
        return System.getenv("JAVA_HOME");
    }

    private Boolean dirExists(String dir) {
        File file = new File(dir);
        return file.exists();
    }
}
